@file:JvmName("Clause")

package dsl

import ast.expr.SqlSubQueryPredicate
import query.select.SelectQuery
import query.select.ValuesSelect

/**
 * 为字段起别名（String类扩展中缀函数）
 * 例如："columnName" alias "aliasName"
 * 或 "columnName".alias("aliasName")
 * @receiver String 字段名
 * @param alias String 别名
 * @return QueryColumn 查询字段表达式
 */
infix fun String.alias(alias: String): QueryColumn {
    return QueryColumn(this, alias)
}

/**
 * 生成一个字段表达式（可以传入字段名或以.分隔的表名+字段名）
 * @param column String 字段名
 * @return QueryColumn 查询字段表达式
 */
fun column(column: String): QueryColumn {
    return QueryColumn(column, null)
}

/**
 * 生成一个字段表达式（参数column可以传入字段名或以.分隔的表名+字段名）
 * @param column String 字段名
 * @param alias String 别名
 * @return QueryColumn 查询字段表达式
 */
fun column(column: String, alias: String): QueryColumn {
    return QueryColumn(column, alias)
}

/**
 * 生成一个查询通配符*
 * @return QueryAllColumn 通配符表达式
 */
fun allColumn(): QueryAllColumn {
    return QueryAllColumn(null)
}

/**
 * 生成一个常量表达式（java中函数名为value）
 * @param value T 常量值（合法的类型有Number、String、Date、List、Boolean以及null）
 * @return QueryConst<T> 常量表达式
 */
@JvmName("value")
fun <T> const(value: T): QueryConst<T> {
    return QueryConst(value)
}

/**
 * 生成一个常量表达式（java中函数名为value）
 * @param value T 常量值（合法的类型有Number、String、Date、List、Boolean以及null）
 * @param alias String 别名
 * @return QueryConst<T> 常量表达式
 */
@JvmName("value")
fun <T> const(value: T, alias: String): QueryConst<T> {
    return QueryConst(value, alias)
}

/**
 * 生成一个CASE WHEN表达式（java中函数名为caseWhen）
 * @param conditions Array<out CaseBranch<T>> CASE匹配分支，为可变参数，可以传入若干个，使用表达式类型Query的then函数即可生成一个CASE分支
 * @return QueryCase<T> CASE WHEN表达式
 */
@JvmName("caseWhen")
fun <T> case(vararg conditions: CaseBranch<T>): QueryCase<T> {
    return QueryCase(conditions.toList())
}

/**
 * 生成一个EXISTS子查询表达式
 * @param select SelectQuery 子查询
 * @return QuerySubQueryPredicate 子查询表达式
 */
fun exists(select: SelectQuery): QuerySubQueryPredicate {
    return QuerySubQueryPredicate(select, SqlSubQueryPredicate.EXISTS)
}

/**
 * 生成一个NOT EXISTS子查询表达式
 * @param select SelectQuery 子查询
 * @return QuerySubQueryPredicate 子查询表达式
 */
fun notExists(select: SelectQuery): QuerySubQueryPredicate {
    return QuerySubQueryPredicate(select, SqlSubQueryPredicate.NOT_EXISTS)
}

/**
 * 生成一个ALL子查询表达式
 * @param select SelectQuery 子查询
 * @return QuerySubQueryPredicate 子查询表达式
 */
fun all(select: SelectQuery): QuerySubQueryPredicate {
    return QuerySubQueryPredicate(select, SqlSubQueryPredicate.ALL)
}

/**
 * 生成一个ANY子查询表达式
 * @param select SelectQuery 子查询
 * @return QuerySubQueryPredicate 子查询表达式
 */
fun any(select: SelectQuery): QuerySubQueryPredicate {
    return QuerySubQueryPredicate(select, SqlSubQueryPredicate.ANY)
}

/**
 * 生成一个SOME子查询表达式
 * @param select SelectQuery 子查询
 * @return QuerySubQueryPredicate 子查询表达式
 */
fun some(select: SelectQuery): QuerySubQueryPredicate {
    return QuerySubQueryPredicate(select, SqlSubQueryPredicate.SOME)
}

/**
 * 生成一个VALUES临时表查询
 * @param values List<List<Any?>> 查询的列表（查询列的合法类型有Number、String、Date、List、Boolean以及null和Query的子类）
 * @return ValuesSelect VALUES查询
 */
fun values(values: List<List<Any?>>): ValuesSelect {
    val valuesSelect = ValuesSelect()

    values.forEach {
        valuesSelect.addRow(it)
    }

    return valuesSelect
}

/**
 * 生成一个VALUES临时表查询
 * @param value Array<out List<Any?>> 查询的列表（查询列的合法类型有Number、String、Date、List、Boolean以及null和Query的子类）
 * @return ValuesSelect VALUES查询
 */
fun values(vararg value: List<Any?>): ValuesSelect {
    return values(value.toList())
}